/* Copyright (c) 2008, Nozomi SATO. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of Nozomi Sato nor the names of its contributors
 *     may be used to endorse or promote products derived from this
 *     software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


#include "doBilinearLine.h"

#define R_INDEX		2
#define G_INDEX		1
#define B_INDEX		0

#define GET_R(x)	x[R_INDEX]
#define GET_G(x)	x[G_INDEX]
#define GET_B(x)	x[B_INDEX]

#define RGB_BPP		3
void doBilinearLine(u8 *pDst, s32 dstWidth, s32 *pWVectors, u8 *pHSamples[], s16 *pU, s32 v)
{
	u8 *p0, *p1, *p2, *p3;
	s32 y0, y1, y2, y3;
	s32 tmp;
	s32 u, opposite_u, opposite_v;
	s32 x;
	u8 *pLine0 = pHSamples[0], *pLine1 = pHSamples[1];
	
	opposite_v = PRECISION_VALUE - v;

	for (x = 0; x < dstWidth; x++) {
		u = pU[x];
		opposite_u = PRECISION_VALUE - u;

		p0 = pLine0 + pWVectors[0] * RGB_BPP;
 		p1 = pLine0 + pWVectors[1] * RGB_BPP;
		p2 = pLine1 + pWVectors[0] * RGB_BPP;
		p3 = pLine1 + pWVectors[1] * RGB_BPP;

		y0 = GET_R(p0);
		y1 = GET_R(p1);
		y2 = GET_R(p2);
		y3 = GET_R(p3);
		tmp = (s32)(y0 * opposite_u + y1 * u) * opposite_v +
			  (s32)(y2 * opposite_u + y3 * u) * v;
		tmp >>= PRECISION_SHIFT * 2;
		pDst[R_INDEX] = tmp;

		y0 = GET_G(p0);
		y1 = GET_G(p1);
		y2 = GET_G(p2);
		y3 = GET_G(p3);
		tmp = (s32)(y0 * opposite_u + y1 * u) * opposite_v +
			  (s32)(y2 * opposite_u + y3 * u) * v;
		tmp >>= PRECISION_SHIFT * 2;
		pDst[G_INDEX] = tmp;

		y0 = GET_B(p0);
		y1 = GET_B(p1);
		y2 = GET_B(p2);
		y3 = GET_B(p3);
		tmp = (s32)(y0 * opposite_u + y1 * u) * opposite_v +
			  (s32)(y2 * opposite_u + y3 * u) * v;
		tmp >>= PRECISION_SHIFT * 2;
		pDst[B_INDEX] = tmp;
		
		pWVectors += 2;
		pDst += RGB_BPP;
	}
}


